package com.mdhw.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mdhw.admin.dao.AdminMenuDao;
import com.mdhw.admin.dao.AdminRoleMenuDao;
import com.mdhw.admin.dao.AdminUserDao;
import com.mdhw.admin.entity.AdminRole;
import com.mdhw.admin.entity.AdminRoleMenu;
import com.mdhw.admin.entity.AdminUser;
import com.mdhw.admin.service.AdminRoleMenuService;
import com.mdhw.admin.service.AdminRoleService;
import com.mdhw.admin.service.AdminUserService;
import com.mdhw.admin.vo.AdminMenuVo;
import com.mdhw.admin.vo.AdminUserVo;
import com.mdhw.common.base.PageData;
import com.mdhw.common.contants.CacheKeyContants;
import com.mdhw.common.enums.MessageEnum;
import com.mdhw.common.enums.StatusEnum;
import com.mdhw.common.jwt.JwtProjectProperties;
import com.mdhw.config.R;
import com.mdhw.utils.EncryptUtil;
import com.mdhw.utils.JwtUtil;
import com.mdhw.utils.RedisUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【admin_user】的数据库操作Service实现
* @createDate 2024-12-04 11:17:04
*/
@Service
public class AdminUserServiceImpl extends ServiceImpl<AdminUserDao, AdminUser> implements AdminUserService{

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private JwtProjectProperties properties;

    @Autowired
    private AdminRoleMenuService adminRoleMenuService;
    @Autowired
    private AdminRoleMenuDao adminRoleMenuDao;
    @Autowired
    private AdminMenuDao adminMenuDao;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private AdminRoleService adminRoleService;
    @Autowired
    private AdminUserDao adminUserDao;

    @Override
    public R<AdminUserVo> login(AdminUserVo adminUserVo) {
        Date nowTime = new Date();
        String loginName = adminUserVo.getLoginName();
        String password = adminUserVo.getPassword();
        LambdaQueryWrapper<AdminUser> auLqw = new LambdaQueryWrapper<>();
        auLqw.eq(AdminUser::getLoginName,loginName);
        auLqw.eq(AdminUser::getStatus, StatusEnum.OK.getCode().toString());
        AdminUser adminUser = this.getOne(auLqw,Boolean.FALSE);
        if(adminUser == null ){
            return R.error(MessageEnum.NO_ACCOUNT.getMessage().toString());
        }

        String salt =adminUser.getSalt();
        // 对明文密码加密处理
        String encrypt = EncryptUtil.encrypt(password, salt);
        String nativePassword = adminUser.getPassword();
        adminUserVo = new AdminUserVo();
        // 判断密码是否正确
        if(encrypt.equals(nativePassword)){
            Long adminUserId = adminUser.getId();
            // 用户角色
            Long roleId = adminUser.getRoleId();
            List<AdminMenuVo> adminMenuVos = this.selectAdminMenuVoByRoleId(roleId,null);
            // 用户接口权限
            List<String> permissionList = new ArrayList<>();
            for(AdminMenuVo sysMenuVo:adminMenuVos){
                permissionList.add(sysMenuVo.getApiUrl());
            }

            String token = JwtUtil.getToken("Houtai", adminUser.getId(), properties.getSecret(), properties.getExpired());
            BeanUtils.copyProperties(adminUser,adminUserVo);
            adminUserVo.setToken(token);
            adminUserVo.setApiUrlList(permissionList);
            adminUserVo.setSysMenuVoList(adminMenuVos);
            adminUserVo.setSysMenuVoList2(adminMenuVos);
            redisUtil.set(CacheKeyContants.ADMIN_USER_TOKEN+adminUserId,token, properties.getExpired());

            redisUtil.set(CacheKeyContants.ADMIN_USER_MENU+adminUserId,adminMenuVos, properties.getExpired());
            redisUtil.set(CacheKeyContants.ADMIN_USER_PERMISSION+adminUserId,permissionList, properties.getExpired());
            return R.success("登录成功",adminUserVo);
        }else {

            return R.error(MessageEnum.AUTH_REQUEST_ERROR.getMessage().toString());
        }

    }


    /**
     * 获取用户详情通过 token
     * @return
     */
    @Override
    public AdminUserVo selectAdminUserByToken() {

        String token = JwtUtil.getRequestToken(request);
        String userIdStr = JwtUtil.parseToken(token);
        if (userIdStr == null) {
            return null;
        }
        Long userId = Long.parseLong(userIdStr);
        AdminUser adminUser = this.getById(userId);
        AdminUserVo adminUserVo = new AdminUserVo();
        BeanUtils.copyProperties(adminUser,adminUserVo);
        Long roleId = adminUser.getRoleId();
        List<AdminMenuVo> sysMenuVoList = this.selectAdminMenuVoByRoleId(roleId,0);
        List<AdminMenuVo> sysMenuVoList2 = new ArrayList<>();
        List<String> apiUrlList = new ArrayList<>();
        for(AdminMenuVo sysMenuVo:sysMenuVoList){
            String type = sysMenuVo.getType();
            Long parentId = sysMenuVo.getParentId();
            String status = sysMenuVo.getStatus();
            if("2".equals(type)) {
                sysMenuVoList2.add(sysMenuVo);
            }

            if("2".equals(type) || "3".equals(type)){
                apiUrlList.add(sysMenuVo.getApiUrl());
            }
        }
        adminUserVo.setApiUrlList(apiUrlList);
        boolean isAdmin = this.isAdmin(null,roleId);

        adminUserVo.setSysMenuVoList(sysMenuVoList);
        adminUserVo.setSysMenuVoList2(sysMenuVoList2);
        adminUserVo.setIsAdmin(isAdmin);

        AdminRole adminRole = this.adminRoleService.getById(roleId);
        adminUserVo.setRoleCode(adminRole.getCode());


        return adminUserVo;
    }


    private List<AdminMenuVo> selectAdminMenuVoByRoleId(Long roleId,Integer isHide){
        LambdaQueryWrapper<AdminRoleMenu> armLqw = new LambdaQueryWrapper<>();
        armLqw.eq(AdminRoleMenu::getRoleId,roleId);
        List<AdminRoleMenu> adminRoleMenuList = this.adminRoleMenuService.list(armLqw);
        List<Long> roleMenuIdList  = adminRoleMenuList.stream().map(AdminRoleMenu::getMenuId).collect(Collectors.toList());
        roleMenuIdList.add(-11L);

        QueryWrapper<AdminMenuVo> amvQw = new QueryWrapper<>();
        amvQw.in("id",roleMenuIdList);
        amvQw.eq("status",StatusEnum.OK.getCode());
        if(isHide != null){
            amvQw.eq("is_hide",isHide);
        }
        // 用户菜单
        List<AdminMenuVo> sysMenuVoList = this.adminMenuDao.selectAdminMenuVoList(amvQw);
        return sysMenuVoList;
    }

    @Override
    public Boolean isAdmin(Long userId,Long roleId){
        if(roleId != null){
            AdminRole adminRole = this.adminRoleService.getById(roleId);
            if(adminRole == null){
                return Boolean.FALSE;
            }
            if("admin".equals(adminRole.getCode())){
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }else if(userId != null){
            AdminUser adminUser = this.getById(userId);
            if(adminUser == null){
                return Boolean.FALSE;
            }
            roleId = adminUser.getRoleId();
            AdminRole adminRole = this.adminRoleService.getById(roleId);
            if(adminRole == null){
                return Boolean.FALSE;
            }
            if("admin".equals(adminRole.getCode())){
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }else{
            return Boolean.FALSE;
        }
    }

    @Override
    public R<PageData<AdminUserVo>> selectAdminUserVoPage(Long pageNo, Long pageSize, String loginName, Long roleId, String name) {
        Page page = new Page(pageNo,pageSize);
        QueryWrapper<AdminUserVo> auvQw = new QueryWrapper<>();
        if(StringUtils.isNotBlank(loginName)){
            auvQw.eq("login_name",loginName);
        }
        if(roleId != null){
            auvQw.eq("role_id",roleId);
        }
        if(StringUtils.isNotBlank(name)){
            auvQw.eq("name",name);
        }
        this.adminUserDao.selectAdminUserVoPage(page,auvQw);
        PageData pageData = PageData.plusPageToPageData(page);
        List<AdminUserVo> dataList = pageData.getData();
        List<Long> roleIdList  = dataList.stream().map(AdminUserVo::getRoleId).collect(Collectors.toList());

        LambdaQueryWrapper<AdminRole> arLqw = new LambdaQueryWrapper<>();
        arLqw.in(AdminRole::getId,roleIdList);
        List<AdminRole> adminRoleList = this.adminRoleService.list(arLqw);

        Map<Long, AdminRole> adminRoleMap = adminRoleList.stream().collect(Collectors.toMap(AdminRole::getId, d -> d, (o, n) -> n));
        for(AdminUserVo adminUserVo:dataList){
            Long roleId1 = adminUserVo.getRoleId();
            AdminRole adminRole = adminRoleMap.get(roleId1);
            if(adminRole != null){
                adminUserVo.setRoleName(adminRole.getName());
            }
            String status = adminUserVo.getStatus();
            if(StatusEnum.OK.getCode().equals(status)){
                adminUserVo.setStatusValue(StatusEnum.OK.getMessage());
            }
            if(StatusEnum.DELETE.getCode().equals(status)){
                adminUserVo.setStatusValue(StatusEnum.DELETE.getMessage());
            }
            if(StatusEnum.DONGJIE.getCode().equals(status)){
                adminUserVo.setStatusValue(StatusEnum.DONGJIE.getMessage());
            }
        }
        return R.success(pageData);
    }


    /**
     * 新增后台用户
     * @param adminUserVo
     * @return
     */
    @Override
    public R<String> addAdminUser(AdminUserVo adminUserVo) {
        AdminUserVo currentAdminUser = this.selectAdminUserByToken();
        if(currentAdminUser == null){
            return R.error("未登录，无权限操作！");
        }
        Boolean isAdmin = currentAdminUser.getIsAdmin();
        if(!isAdmin){
            return R.error("非超级管理员，无权限操作！");
        }
        Date nowTime = new Date();

        AdminUser  adminUser = new AdminUser();
        adminUser.setCreateDate(nowTime);
        adminUser.setUpdateDate(nowTime);
        adminUser.setRevision(0);
        adminUser.setStatus(StatusEnum.OK.getCode().toString());
        adminUser.setSortNum(0);
        //生成盐值
        String salt = EncryptUtil.getRandomSalt();
        String pwd = EncryptUtil.encrypt(adminUserVo.getPassword(), salt);
        adminUser.setPassword(pwd);
        adminUser.setSalt(salt);
        adminUser.setLoginName(adminUserVo.getLoginName());
        adminUser.setPhone(adminUserVo.getPhone());
        adminUser.setName(adminUserVo.getName());
        adminUser.setRoleId(adminUserVo.getRoleId());
        boolean isSuccess = this.save(adminUser);
        if(isSuccess){
            return R.success();
        }else{
            return R.error("新增失败！");
        }
    }

    /**
     * 修改后台用户
     * @param adminUserVo
     * @return
     */
    @Override
    public R<String> updateAdminUser(AdminUserVo adminUserVo) {
        AdminUserVo currentAdminUser = this.selectAdminUserByToken();
        if(currentAdminUser == null){
            return R.error("未登录，无权限操作！");
        }
        Boolean isAdmin = currentAdminUser.getIsAdmin();
        if(!isAdmin){
            return R.error("非超级管理员，无权限操作！");
        }
        Date nowTime = new Date();
        Long id = adminUserVo.getId();
        if(id == null){
            return R.error("该用户不存在");
        }
        AdminUser adminUser = this.getById(id);
        BeanUtils.copyProperties(adminUserVo,adminUser);
        adminUser.setUpdateDate(nowTime);
        boolean isSuccess = this.updateById(adminUser);
        if(isSuccess){
            return R.success();
        }else{
            return R.error("修改失败！");
        }
    }

    /**
     * 后台用户重置密码
     * @param adminUserVo
     * @return
     */
    @Override
    public R<String> resetPassword(AdminUserVo adminUserVo) {
        AdminUserVo currentAdminUser = this.selectAdminUserByToken();
        if(currentAdminUser == null){
            return R.error("未登录，无权限操作！");
        }
        Boolean isAdmin = currentAdminUser.getIsAdmin();
        if(!isAdmin){
            return R.error("非超级管理员，无权限操作！");
        }
        Date nowTime = new Date();
        Long id = adminUserVo.getId();
        if(id == null){
            return R.error("该用户不存在");
        }
        AdminUser adminUser = this.getById(id);
        String newPassword = "Sjlh@Xm2025!666";
        String salt = EncryptUtil.getRandomSalt();
        String pwd = EncryptUtil.encrypt(newPassword, salt);
        adminUser.setSalt(salt);
        adminUser.setPassword(pwd);
        adminUser.setUpdateDate(nowTime);
        boolean isSuccess = this.updateById(adminUser);
        if(isSuccess){
            return R.success();
        }else{
            return R.error("修改失败！");
        }
    }

    @Override
    public R<String> setStatus(AdminUserVo adminUserVo) {
        AdminUserVo currentAdminUser = this.selectAdminUserByToken();
        if(currentAdminUser == null){
            return R.error("未登录，无权限操作！");
        }
        Boolean isAdmin = currentAdminUser.getIsAdmin();
        if(!isAdmin){
            return R.error("非超级管理员，无权限操作！");
        }
        Date nowTime = new Date();
        Long id = adminUserVo.getId();
        if(id == null){
            return R.error("该用户不存在");
        }
        AdminUser adminUser = this.getById(id);
        adminUser.setUpdateDate(nowTime);
        if(StatusEnum.OK.getCode().equals(adminUser.getStatus())){
            adminUser.setStatus(StatusEnum.DONGJIE.getCode());
        }else if(StatusEnum.DONGJIE.getCode().equals(adminUser.getStatus())){
            adminUser.setStatus(StatusEnum.OK.getCode());
            // 删除 token
            this.redisUtil.del(CacheKeyContants.ADMIN_USER_TOKEN+id);
            this.redisUtil.del(CacheKeyContants.ADMIN_USER_MENU+id);
            this.redisUtil.del(CacheKeyContants.ADMIN_USER_PERMISSION+id);
        }
        boolean isSuccess = this.updateById(adminUser);
        if(isSuccess){
            return R.success();
        }else{
            return R.error("修改失败！");
        }
    }

    @Override
    public R<String> deleteAdminUser(AdminUserVo adminUserVo) {
        AdminUserVo currentAdminUser = this.selectAdminUserByToken();
        if(currentAdminUser == null){
            return R.error("未登录，无权限操作！");
        }
        Boolean isAdmin = currentAdminUser.getIsAdmin();
        if(!isAdmin){
            return R.error("非超级管理员，无权限操作！");
        }
        Date nowTime = new Date();
        Long id = adminUserVo.getId();
        if(id == null){
            return R.error("该用户不存在");
        }
        AdminUser adminUser = this.getById(id);
        adminUser.setUpdateDate(nowTime);
        adminUser.setStatus(StatusEnum.DELETE.getCode());
        boolean isSuccess = this.updateById(adminUser);
        if(isSuccess){
            // 删除 token
            this.redisUtil.del(CacheKeyContants.ADMIN_USER_TOKEN+id);
            this.redisUtil.del(CacheKeyContants.ADMIN_USER_MENU+id);
            this.redisUtil.del(CacheKeyContants.ADMIN_USER_PERMISSION+id);
            return R.success();
        }else{
            return R.error("修改失败！");
        }
    }
}




